package com.bjtu.ptsite.interceptor;


import com.bjtu.ptsite.model.Result;
import com.bjtu.ptsite.utils.JwtUtils;
import com.bjtu.ptsite.utils.RequestUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.protocol.ResponseAuthCache;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;


@Slf4j
@Component
/**
 * 拦截器，需要验证token拦截不合法用户
 * @author Zehao Wang, Junjie Zhang, Yutao Wei
 */
public class Interceptor implements HandlerInterceptor
{
    public static final String LOGIN = "login";
    public static final String REGISTER = "register";
    public static final String REGISTER_VERIFICATION = "registerVerification";
    public static final String SWAGGER_UI = "swagger-ui";
    public static final String SWAGGER_CONFIG = "swagger-config";
    public static final String API_DOCS = "v3/api-docs";
    public static final String ANNOUNCE = "announce";
    /**
     * 拦截前运行  在此处做登录校验操作
     */
    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {

        //此时没有必要强转了，因为prehandle传进来的就是HttpServletRequest类的

        //获取请求的url
        String url=req.getRequestURI();

        //判断url是否含有login关键字
        if(url.contains(LOGIN) || url.contains(REGISTER)
                || url.contains(REGISTER_VERIFICATION)
                || url.contains(SWAGGER_UI)
                || url.contains(SWAGGER_CONFIG)
                || url.contains(API_DOCS)
                || url.contains(ANNOUNCE)){


            //返回true表示放行
            return true;
        }//如果包含则放行

        //如果不是登录操作，需要获取令牌jwt(token)
        String token = req.getHeader("token");
        //判断令牌是否存在

        if(!StringUtils.hasLength(token))
        {
            Result notLogin = Result.error("NOT_LOGIN");

            String json = new ObjectMapper().writeValueAsString(notLogin);
            resp.getWriter().write(json);
            //如果令牌不存在，那么不能放行
            return false;

        }
        //如果jwt存在，那么校验令牌，如果合理则放行
        try {
            //如果报错，说明解析失败，令牌不合理
            Claims claims = JwtUtils.parseJwt(token);
            int identificationNumber = Integer.parseInt(claims.get("identificationNumber").toString());
            int userId = claims.get("id", Integer.class);
            RequestUtil.setUserContext(userId, identificationNumber);
        } catch (Exception e) {//jwt解析失败
            e.printStackTrace();

            Result notLogin = Result.error("NOT_LOGIN");

            String json = new ObjectMapper().writeValueAsString(notLogin);
            resp.getWriter().write(json);
            //令牌不合理也不能放行
            return false;
        }

        //存在则放行

        return true;
    }

    /**
     * 拦截后运行
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    /**
     * 最后运行
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
        RequestUtil.clear();
    }
}
